[Rust] actix-webを使ってみよう
What is actix?
actixとは、Rust製のActorフレームワークです。
(Java/Scalaでいうと、Akkaがメジャーですね)
アクター同士が非同期でメッセージをやり取りし、安全に並行処理を行うことができます。
そのactixをベースとしてWeb開発用機能を追加したのが、
軽量・高速なWeb開発フレームワークであるactix-webです。
actix-webで開発されたアプリは、実行ファイルにHTTPサーバーを含んでいるため、
そのまま使うこともできるし、apacheやnginxの後ろに置くこともできます。
Environment
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.15.1
- Rust : 1.42.0
※actix-webはRust 1.39以降で動作します
Setup Rust & actix-web
※Rustのインストール方法についてはこちらもご覧ください
ではRustをインストールしてサンプルプロジェクトをつくってみましょう。
まずはrustup(Rustのインストーラ)をインストールします。
% curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
↑のコマンドでインストール後、terminalを再起動したら、問題ないか確認。
% rustup -V rustup 1.21.1 (7832b2ebe 2019-12-20)
Rustが1.39以降でないなら、uddateします。
% rustup update
Rustのバージョンも更新されました。
%rustc --version rustc 1.42.0 (b8cedc004 2020-03-09)
Cargoを使ってプロジェクトを作成します。
% cargo new actix-sample Created binary (application) `actix-sample` package
actix-example/Cargo.tomlで依存ライブラリ(actix-webとactix-rt)を設定します。
[package] name = "actix-sample" version = "0.1.0" authors = ["・・・・・"] edition = "2018" [dependencies] actix-web = "2.0" actix-rt = "1.0"
src/main.rsを編集。3000番ポートでHTTPサーバが起動するようにします。
use actix_web::{web, App, HttpResponse, HttpServer, Responder}; async fn index() -> impl Responder { HttpResponse::Ok().body("Hello world!") } async fn index2() -> impl Responder { HttpResponse::Ok().json("{\"message\":\"Hello world again!\"}") } #[actix_rt::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .route("/", web::get().to(index)) .route("/again", web::get().to(index2)) }) .bind("127.0.0.1:8088")? .run() .await }
runコマンドでアプリを起動しましょう。
http://localhosat:3000にアクセスすれば、Hello Worldが表示されます。
http://localhosat:3000/againにアクセスすれば、json形式でレスポンスが返されます。
% cargo run
とてもシンプルなプログラムですが、ソースのポイントをいくつか説明します。
- index/index2関数
パスと紐付けるためのリクエストハンドラを作成しています。
これはHttpRequestを受け取り(optional)、Responderをimplimentsした非同期関数となります。
- main関数
Appインスタンスを作成し、パスとリクエストハンドラを登録します。
そしてHttpServerでAppインスタンスを使用し、8088番ポートで起動します。
なお、ここでは、main関数に、actix_rt::mainマクロを記述しています。
(Actixに実行される非同期関数をマークするためのマクロ)
そして、main関数にもasyncをつけます。
※ async/awaitについてはこのへん参照
新しくパスを追加してみましょう。
今度はgetマクロを使ってハンドラを定義します。
・・・ use actix_web::get; #[get("/macro-path")] async fn index3() -> impl Responder { HttpResponse::Ok().body("response from index3!") } ・・・
service関数でindex3を追加しましょう。
他のハンドラよりさらにシンプルに追加できました。
・・・ #[actix_rt::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .route("/", web::get().to(index)) .route("/again", web::get().to(index2)) .service(index3) // これを追加 }) .bind("127.0.0.1:8088")? .run() .await }
まとめ
とりあえずactix-webを動かすことはできました。
基本的な解説はここにありますし、
Gihubにはいろいろなactix-webのサンプルプログラムもありますので、
これらを参考にしてみてください。